package com.yonyou.cyxdms.basedata.service.service.region;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yonyou.cyx.framework.compent.redis.RedisClient;
import com.yonyou.cyx.framework.util.bean.ApplicationContextHelper;
import com.yonyou.cyx.function.utils.bean.BeanMapperUtil;
import com.yonyou.cyx.function.utils.jsonserializer.JSONUtil;
import com.yonyou.cyxdms.basedata.client.domains.vo.RegionVO;
import com.yonyou.cyxdms.basedata.client.dto.RegionConditionDTO;
import com.yonyou.cyxdms.basedata.service.constant.BasedataCommonConstants;
import com.yonyou.cyxdms.basedata.service.constant.BasedataDictConstants;
import com.yonyou.cyxdms.basedata.service.dto.JsonRegionDTO;
import com.yonyou.cyxdms.basedata.service.entity.basedata.SystemParamPO;
import com.yonyou.cyxdms.basedata.service.entity.region.RegionPO;
import com.yonyou.cyxdms.basedata.service.repository.region.RegionMapper;
import com.yonyou.cyxdms.basedata.service.service.brand.BrandService;
import com.yonyou.cyxdms.basedata.service.vo.region.AllCityVO;
import com.yonyou.cyxdms.basedata.service.vo.region.AllDistVO;
import com.yonyou.cyxdms.basedata.service.vo.region.AllRegionVO;
import com.yonyou.cyxdms.basedata.service.vo.region.SpAllCityInfoVO;
import com.yonyou.cyxdms.framework.bean.dto.user_info.LoginInfoDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 地区表 服务实现类
 * </p>
 *
 * @author renwd
 * @since 2018-12-19
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class RegionServiceImpl implements RegionService {

    public static final Logger logger = LoggerFactory.getLogger(RegionServiceImpl.class);

    @Autowired
    RegionMapper regionMapper;

    @Autowired
    private BrandService brandService;

    @Autowired
    private RedisClient redisClient;

    /**
     * 查询所有省份
     *
     * @return java.util.List<java.util.Map       <       java.lang.String       ,       java.lang.Object>>
     * @author renwd
     * @since 2018/12/19
     */
    @Override
    public List<RegionPO> listAllProvice() {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        QueryWrapper<RegionPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RegionPO::getRegionType, BasedataDictConstants.PROVICE)
                .eq(RegionPO::getAppId, loginInfoDto.getAppId());
        return regionMapper.selectList(queryWrapper);
    }

    /**
     * 根据省id查询市信息、根据市id查询区信息
     *
     * @return java.util.List<java.util.Map       <       java.lang.String       ,       java.lang.Object>>
     * @author renwd
     * @since 2018/12/19
     */
    @Override
    public List<RegionPO> listDataById(Long provinceId) {
        QueryWrapper<RegionPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RegionPO::getParentRegionId, provinceId);
        return regionMapper.selectList(queryWrapper);
    }

    /**
     * 查询所有数据
     *
     * @param
     * @return java.util.List<com.yonyou.cyxdms.basedata.service.vo.region.RegionVO>
     * @author renwd
     * @since 2019/7/12
     */
    @Override
    public List<RegionVO> listAllData() {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        QueryWrapper<RegionPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RegionPO::getAppId, loginInfoDto.getAppId());
        List<RegionPO> regionPoList = regionMapper.selectList(queryWrapper);
        List<RegionVO> regionVOList = new ArrayList<>();
        regionPoList.stream().forEach(regionPo -> {
            RegionVO regionVO = BeanMapperUtil.copyProperties(regionPo, RegionVO.class);
            regionVOList.add(regionVO);
        });
        return regionVOList;
    }

    @Override
    public List<RegionVO> listAllDataByAppId(String appId) {
        QueryWrapper<RegionPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RegionPO::getAppId, appId);
        List<RegionPO> regionPoList = regionMapper.selectList(queryWrapper);
        List<RegionVO> regionVOList = new ArrayList<>();
        regionPoList.stream().forEach(regionPo -> {
            RegionVO regionVO = BeanMapperUtil.copyProperties(regionPo, RegionVO.class);
            regionVOList.add(regionVO);
        });
        return regionVOList;
    }

    /**
     * 根据type查询省市区
     *
     * @param regionCode
     * @return java.util.List<com.yonyou.cyxdms.basedata.service.vo.region.RegionVO>
     * @author renwd
     * @since 2019/7/12
     */
    @Override
    public List<RegionVO> listAllDataByType(String regionCode) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        QueryWrapper<RegionPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RegionPO::getAppId, loginInfoDto.getAppId())
                .eq(RegionPO::getRegionCode, regionCode);
        List<RegionPO> regionPoList = regionMapper.selectList(queryWrapper);
        List<RegionVO> regionVOList = new ArrayList<>();
        regionPoList.stream().forEach(regionPo -> {
            RegionVO regionVO = BeanMapperUtil.copyProperties(regionPo, RegionVO.class);
            regionVOList.add(regionVO);
        });
        return regionVOList;
    }

    /**
     * 查询省市区县数据
     *
     * @param
     * @return java.util.List<java.util.Map   <   java.lang.String   ,   java.lang.Object>>
     * @author renwd
     * @since 2018/12/27
     */
    @Override
    public List<AllRegionVO> listAllRegionData() {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        String appId = loginInfoDto.getAppId();
        logger.info("appId:-------------{}", appId);
        // 查询系统参数表 - 省市区转发URL
        SystemParamPO systemParamPo = brandService.queryRedirectUrl(appId, BasedataCommonConstants.QUERY_REGION);
        if (systemParamPo != null) {
            String url = systemParamPo.getParamValue();
            String response = brandService.getRedirectResponse(appId, url);
            logger.info("response:-----------------{}", response);
            Map<String, Object> map = JSONUtil.jsonToMap(response);
            return JSONUtil.jsonToList(JSONUtil.objectToJson(map.get("data")), AllRegionVO.class);
        } else {
            List<JsonRegionDTO> regionData = regionMapper.listAllRegionData(loginInfoDto.getAppId(), BasedataDictConstants.PROVICE);
            List<AllRegionVO> mapReturn = new ArrayList<>();
            String preProvince = "";
            String preCity = "";
            List<AllCityVO> cityList = new ArrayList<>();
            List<AllDistVO> dictList = new ArrayList<>();

            for (int i = 0; i < regionData.size(); i++) {
                JsonRegionDTO region = regionData.get(i);

                if (!preProvince.equals(region.getProvinceCode())) {
                    AllRegionVO provinceMap = new AllRegionVO();
                    cityList = new ArrayList<>();
                    provinceMap.setProvinceCode(region.getProvinceCode());
                    provinceMap.setProvinceName(region.getProvinceName());
                    provinceMap.setProvinceId(region.getProvinceId());
                    provinceMap.setCity(cityList);
                    preProvince = region.getProvinceCode();
                    mapReturn.add(provinceMap);
                }

                // 避免城市code为空
                if (null == region.getCityCode()) {
                    continue;
                }

                if (!preCity.equals(region.getCityCode())) {
                    AllCityVO cityMap = new AllCityVO();
                    dictList = new ArrayList<>();
                    cityMap.setCityCode(region.getCityCode());
                    cityMap.setCityName(region.getCityName());
                    cityMap.setCityId(region.getCityId());
                    cityMap.setDist(dictList);
                    preCity = region.getCityCode();
                    cityList.add(cityMap);
                }
                AllDistVO data = new AllDistVO();
                data.setDistCode(region.getDistCode());
                data.setDistName(region.getDistName());
                data.setDistId(region.getDistId());
                dictList.add(data);
            }
            return mapReturn;
        }
    }

    /**
     * 根据关键字检索城市列表
     *
     * @param forWord
     * @return
     * @author houkh
     * @since 2019/8/22
     */
    @Override
    public Map<String, Object> cityInfo(String forWord) {
        Map<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<RegionPO> queryWrapper = new QueryWrapper<RegionPO>().lambda();
        // todo 暂时写死
        queryWrapper.eq(RegionPO::getAppId, "cyx");
        queryWrapper.eq(RegionPO::getIsDeleted, 0);
        queryWrapper.eq(RegionPO::getHotCity, 1);
        queryWrapper.eq(RegionPO::getRegionType, 10001002);
        List<Map<String, Object>> hotList = regionMapper.selectMaps(queryWrapper);
        map.put("hotCity", hotList);
        List<Map<String, Object>> cityList = regionMapper.cityInfo(forWord);
        map.put("groupCity", cityList);
        return map;
    }

    /**
     * 省市映射
     *
     * @param provinceName
     * @param cityName
     * @return java.util.Map<java.lang.String   ,       java.lang.Long>
     * @author tanjie
     * @since 2019/9/10
     */
    @Override
    public Map<String, Long> getRegion(String provinceName, String cityName) {
        Map<String, Long> map = new HashMap<>();
        LambdaQueryWrapper<RegionPO> query = new QueryWrapper<RegionPO>().lambda();
        query.eq(RegionPO::getRegionType, BasedataDictConstants.PROVICE);
        query.eq(RegionPO::getRegionName, provinceName);
        List<RegionPO> regionPos = regionMapper.selectList(query);
        map.put("PROVICE", null != regionPos && regionPos.size() > 0 && provinceName != null ?
                regionPos.get(0).getRegionId() : null);
        query = new QueryWrapper<RegionPO>().lambda();
        query.eq(RegionPO::getRegionType, BasedataDictConstants.CITY);
        query.eq(RegionPO::getRegionName, cityName);
        regionPos = regionMapper.selectList(query);
        map.put("CITY", null != regionPos && regionPos.size() > 0 && cityName != null ? regionPos.get(0).getRegionId() :
                null);
        return map;
    }

    /**
     * 根据省市区查询对应的信息
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/10/17
     */
    @Override
    public List<RegionVO> getProvinceRelatedData(List ids) {

        return BeanMapperUtil.copyList(regionMapper.selectBatchIds(ids), RegionVO.class);
    }

    /**
     * 通用根据城市名称查询省市区ID列表
     *
     * @param regionConditionDTO
     * @return java.util.List<java.lang.Long>
     * @author dengqiang
     * @since 2019/10/31
     */
    @Override
    public List<Long> getRegionIdList(RegionConditionDTO regionConditionDTO) {
        Integer regionLevel = regionConditionDTO.getRegionLevel();
        List<Integer> regionTypeList = new ArrayList<>();
        if (null == regionLevel) {
            return regionMapper.getRegionIdList(regionConditionDTO.getRegionName(), regionTypeList, regionConditionDTO.getIsLike());
        } else if (1 == regionLevel) {
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_PROVINCE);
        } else if (2 == regionLevel) {
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_CITY);
        } else if (3 == regionLevel) {
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_DISTRICT);
        } else if (4 == regionLevel) {
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_PROVINCE);
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_CITY);
        } else if (5 == regionLevel) {
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_CITY);
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_DISTRICT);
        } else if (6 == regionLevel) {
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_PROVINCE);
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_DISTRICT);
        } else {
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_PROVINCE);
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_CITY);
            regionTypeList.add(BasedataCommonConstants.REGION_TYPE_DISTRICT);
        }
        return regionMapper.getRegionIdList(regionConditionDTO.getRegionName(), regionTypeList, regionConditionDTO.getIsLike());
    }

    /**
     * 根据名称获取对应ID
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/11/4
     */
    @Override
    public RegionVO mappingRegionName(Integer regionType, String regionName, String appId, Long parentId) {
        if (regionName == null) {
            return null;
        }
        LambdaQueryWrapper<RegionPO> query = null;
        if (parentId == null) {
            query = new QueryWrapper<RegionPO>().lambda().eq(RegionPO::getRegionType,
                    regionType).
                    eq(RegionPO::getRegionName, regionName).
                    eq(RegionPO::getAppId, appId).
                    isNull(RegionPO::getParentRegionId);
        } else {
            query = new QueryWrapper<RegionPO>().lambda().eq(RegionPO::getRegionType,
                    regionType).
                    eq(RegionPO::getRegionName, regionName).
                    eq(RegionPO::getAppId, appId).
                    eq(RegionPO::getParentRegionId, parentId);
        }

        RegionPO regionPo = this.regionMapper.selectOne(query);
        return BeanMapperUtil.copyProperties(regionPo, RegionVO.class);
    }

    /**
     * ID查地区
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/11/4
     */
    @Override
    public RegionVO getRegionById(Long id) {
        RegionPO regionPo = this.regionMapper.selectById(id);
        return BeanMapperUtil.copyProperties(regionPo, RegionVO.class);
    }

    @Override
    public RegionVO getRegionByCode(String code, String appId) {
        LambdaQueryWrapper<RegionPO> query =
                new QueryWrapper<RegionPO>().lambda().eq(RegionPO::getRegionCode, code).eq(RegionPO::getAppId, appId);
        RegionPO regionPo = regionMapper.selectOne(query);
        return null == regionPo ? null : BeanMapperUtil.copyProperties(regionPo, RegionVO.class);
    }

    /**
     * APPID查region
     * 未登陆
     *
     * @param appid
     * @return:
     * @auther: tanjie
     * @since: 2019/11/14
     */
    @Override
    public List<RegionVO> getAllRegion(String appid) {
        LambdaQueryWrapper<RegionPO> region = new QueryWrapper<RegionPO>().lambda().eq(RegionPO::getAppId, appid);
        List<RegionPO> result = this.regionMapper.selectList(region);
        return BeanMapperUtil.copyList(result, RegionVO.class);
    }

    /**
     * 前端定置化接口
     *
     * @param
     * @return com.yonyou.cyxdms.basedata.service.vo.region.SpAllCityInfoVO
     * @author houkh
     * @since 2019/12/2
     */
    @Override
    public SpAllCityInfoVO spCityInfo() {
        String appId = ApplicationContextHelper.getBeanByType(LoginInfoDto.class).getAppId();
        String cacheKey = "spcity:" + appId;
        if (redisClient.exists(cacheKey)) {
            return JSONUtil.jsonToObj((String) redisClient.get(cacheKey), SpAllCityInfoVO.class);
        } else {
            List<AllRegionVO> sourceReginList = listAllRegionData();
            Map<String, List<SpAllCityInfoVO.SpBaseCityInfo>> citys = new HashMap<>();
            List<SpAllCityInfoVO.SpBaseCityInfo> provinceInfoList = new ArrayList<>();
            for (AllRegionVO regionVO : sourceReginList) {
                SpAllCityInfoVO.SpBaseCityInfo province = new SpAllCityInfoVO.SpBaseCityInfo();
                province.setCode(regionVO.getProvinceCode());
                province.setAddress(regionVO.getProvinceName());
                provinceInfoList.add(province);
                List<SpAllCityInfoVO.SpBaseCityInfo> cityInfoList = new ArrayList<>();
                for (AllCityVO cityVO : regionVO.getCity()) {
                    SpAllCityInfoVO.SpBaseCityInfo city = new SpAllCityInfoVO.SpBaseCityInfo();
                    city.setCode(cityVO.getCityCode());
                    city.setAddress(cityVO.getCityName());
                    cityInfoList.add(city);
                    List<SpAllCityInfoVO.SpBaseCityInfo> distInfoList = new ArrayList<>();
                    for (AllDistVO distVO : cityVO.getDist()) {
                        SpAllCityInfoVO.SpBaseCityInfo dist = new SpAllCityInfoVO.SpBaseCityInfo();
                        dist.setCode(distVO.getDistCode());
                        dist.setAddress(distVO.getDistName());
                        distInfoList.add(dist);
                    }
                    citys.put(city.getCode(), distInfoList);
                }
                citys.put(province.getCode(), cityInfoList);
            }
            SpAllCityInfoVO result = new SpAllCityInfoVO();
            result.setProvinceList(provinceInfoList);
            result.setCityInfos(citys);
            // 有数据才做缓存
            if (!CollectionUtils.isEmpty(provinceInfoList)) {
                redisClient.set(cacheKey, JSONUtil.objectToJson(result), BasedataCommonConstants.EXPIRE_TIME_ONE_HOUR);
            }
            return result;
        }
    }

}

